# -*- coding: utf-8 -*-
# contextlib
 
from contextlib import contextmanager

# __enter__和__exit__这两个方法实现,就可以用with语句进行管理

# class Query(object):
# 	def __init__(self,name):
# 		self.name = name

# 	def __enter__(self):
# 		print('Begin')
# 		return self

# 	def __exit__(self,exc_type,exc_value,traceback):
# 		if exc_type:
# 			print('Error')
# 		else:
# 			print('End')
# 	def query(self):
# 		print('Query info about %s...' % self.name)
	
# with Query('Bob') as q:
	# q.query()

# 使用contextlib实现
class Query(object):
	def __init__(self,name):
		self.name=name
	def query(self):
		print('Query info about %s...' % self.name)

@contextmanager
def create_query(name):
	print('Begin')
	q = Query(name)
	yield q
	print('End')

with create_query('Bob') as q:
	q.query()

# 很多时候，我们希望在某段代码执行前后自动执行特定代码，也可以使用@contextmanager

@contextmanager
def tag(name):
	print('<%s>' % name)
	yield
	print('</%s>' % name)

with tag('h1'):
	print('hello')
	print('world')


####代码执行顺序：
# 1：with语句首先执行yield之前的语句，因此答应出<h1>
# 2：yield调用会执行with语句内部的所有语句，因此打印出hello和world
# 3：最后执行yield之后的语句,打印出</h1>

#### @closing 把对象变为上下文对象，方可使用with语句
from contextlib import closing
from urllib.request import urlopen

with closing(urlopen('https://www.python.org')) as page:
	for line in page:
		print(line)

#### closing() 也是一个经过@contextmanager装饰的generator
@contextmanager
def closing(thing):
	try:
		yield thing
	finally:
		thing.close()